'use strict';

/**
 * 日期时间类
 * format: yyyy-MM-dd | yyyy-MM-dd hh:mm:ss
 */
export default class DateTime {
  constructor(d) {
    // 没有传入参数或传入参数为null
    if ((typeof d === 'undefined') || d === null) {
      this.date = new Date();
      return this;
    }
    // 数字类型，传入格式: new Date().getTime()
    if (typeof d === 'number') {
      this.date = new Date(d);
      return this;
    }
    // 字符串类型，传入格式：yyyy-MM-dd
    if (typeof d === 'string' && d.length == 10) {
      var year = parseInt(d.substr(0, 4));
      var month = parseInt(d.substr(5, 2)) - 1;
      var day = parseInt(d.substr(8, 2));
      this.date = new Date(year, month, day);
      return this;
    }
    // 字符串类型，传入格式：yyyy-MM-dd hh:mm
    if (typeof d === 'string' && d.length == 16) {
      var year = parseInt(d.substr(0, 4));
      var month = parseInt(d.substr(5, 2)) - 1;
      var day = parseInt(d.substr(8, 2));
      var hours = parseInt(d.substr(11, 2));
      var minutes = parseInt(d.substr(14, 2));
      var seconds = 0;
      this.date = new Date(year, month, day, hours, minutes, seconds);
      return this;
    }
    // 字符串类型，传入格式：yyyy-MM-dd hh:mm:ss
    if (typeof d === 'string' && d.length == 19) {
      var year = parseInt(d.substr(0, 4));
      var month = parseInt(d.substr(5, 2)) - 1;
      var day = parseInt(d.substr(8, 2));
      var hours = parseInt(d.substr(11, 2));
      var minutes = parseInt(d.substr(14, 2));
      var seconds = parseInt(d.substr(17, 2));
      this.date = new Date(year, month, day, hours, minutes, seconds);
      return this;
    }
    // 其他类型或格式未实现，直接返回当前时间
    this.date = new Date();
    return this;
  }

  /**
   * 转化为指定格式的String
   *
   * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
   * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
   * 例子：
   * to("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
   * to("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
   * @param {String} fmt 格式字符串
   */
  to(fmt) {
    var o = {
      "M+": this.date.getMonth() + 1, //月份
      "d+": this.date.getDate(), //日
      "h+": this.date.getHours(), //小时
      "m+": this.date.getMinutes(), //分
      "s+": this.date.getSeconds(), //秒
      "q+": Math.floor((this.date.getMonth() + 3) / 3), //季度
      "S": this.date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(RegExp.$1, (this.date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
      if (new RegExp("(" + k + ")").test(fmt))
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
  };

  toDate() {
    return this.to("yyyy-MM-dd");
  };

  toDateTime() {
    return this.to("yyyy-MM-dd hh:mm:ss");
  };

  toDateTimeStart() {
    if(this.date.getHours() < 6){
      this.addDay(-1);
    }
    return this.to("yyyy-MM-dd 06:00:00");
  };

  toDateTimeEnd() {
    if(this.date.getHours() >= 6){
      this.addDay(1);
    }
    return this.to("yyyy-MM-dd 06:00:00");
  };

  toTDateTime() {
    return this.to("yyyy-MM-ddThh:mm:ss");
  };

  toTDateTimeStart() {
    if(this.date.getHours() < 6){
      this.addDay(-1);
    }
    return this.to("yyyy-MM-ddT06:00:00");
  };

  toTDateTimeEnd() {
    if(this.date.getHours() >= 6){
      this.addDay(1);
    }
    return this.to("yyyy-MM-ddT06:00:00");
  };

  toTime() {
    return this.to("hh:mm:ss");
  };

  toHHMM() {
    return this.to("hh:mm");
  };

  /**
   * 日期时间加减
   */
  addSeconds(seconds) {
    this.date = new Date(this.date.getTime() + seconds * 1000);
    return this;
  };

  addMinutes(minutes) {
    this.date = new Date(this.date.getTime() + minutes * 60 * 1000);
    return this;
  };

  addHours(hours) {
    this.date = new Date(this.date.getTime() + hours * 60 * 60 * 1000);
    return this;
  };

  addDay(days) {
    this.date = new Date(this.date.getTime() + days * 24 * 60 * 60 * 1000);
    return this;
  };

  addMonth(months) {
    var arr_month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    var o = {
      "year": this.date.getFullYear(),//年
      "month": this.date.getMonth(), //月份
      "date": this.date.getDate(), //日
      "hours": this.date.getHours(), //小时
      "minutes": this.date.getMinutes(), //分
      "seconds": this.date.getSeconds(), //秒
      "milliseconds": this.date.getMilliseconds() //毫秒
    };
    //润年，二月29天
    if ((o.year % 4 == 0 && o.year % 100 != 0) || o.year % 400 == 0) {
      arr_month_days[1] = 29;
    }
    o.year += parseInt(months / 12);
    o.month += months % 12;
    if (o.month < 0) {
      o.month += 12;
      o.year -= 1;
    } else if (o.month >= 12) {
      o.month -= 12;
      o.year += 1;
    }
    if (o.date > arr_month_days[o.month]) {
      o.date = arr_month_days[o.month];
    }
    this.date = new Date(o.year, o.month, o.date, o.hours, o.minutes, o.seconds, o.milliseconds);
    return this;
  };
}

/**
 * 追加静态方法
 *
 * @param d 时间参数
 * @returns {DateTime}
 */
DateTime.of = (d) => new DateTime(d);
